import {
  AmbientLight,
  AxesHelper,
  BoxGeometry,
  CubeTextureLoader,
  DirectionalLight,
  GridHelper,
  Group,
  Mesh,
  MeshBasicMaterial,
  MeshStandardMaterial,
  PerspectiveCamera,
  Scene,
  Vector3,
  WebGLRenderer,
} from "three";
import { GLTFLoader, OrbitControls } from "three/examples/jsm/Addons.js";

export default class Y3DEngine {
  constructor() {
    this.init();
    this.animate();
  }

  get width() {
    return window.innerWidth;
  }

  get height() {
    return window.innerHeight;
  }

  get aspect() {
    return this.width / this.height;
  }

  animate = () => {
    requestAnimationFrame(this.animate);
    this.renderer.render(this.scene, this.camera);
  };

  init() {
    this.createScene();
    this.createCamera();
    this.createRenderer();
    this.createLight();
    this.createObject();
    this.createControls();
    this.createHelper();
    this.initEvent();
  }

  createScene() {
    this.scene = new Scene();
  }

  createHelper() {
    this.helpers = new Group();
    this.scene.add(this.helpers);

    const gridHelper = new GridHelper(10, 10);
    this.helpers.add(gridHelper);

    const axesHelper = new AxesHelper(10);
    this.helpers.add(axesHelper);
  }

  createCamera() {
    this.camera = new PerspectiveCamera(75, this.aspect, 0.1, 10000);
    this.camera.position.set(0, 0, 3);
  }

  createRenderer() {
    this.renderer = new WebGLRenderer({
      antialias: true,
      alpha: true,
    });
    this.renderer.setSize(this.width, this.height);
    this.renderer.setClearColor(0x272727, 1);
    this.renderer.setPixelRatio(window.devicePixelRatio);
    document.body.appendChild(this.renderer.domElement);
  }

  createLight() {
    this.lights = new Group();
    this.scene.add(this.lights);
    const light = new AmbientLight(0xffffff, 0.3);
    this.lights.add(light);

    const light1 = new DirectionalLight(0xffffff, 0.8);
    light1.position.set(1, 1, 0);
    this.lights.add(light1);

    const light2 = new DirectionalLight(0xffffff, 0.5);
    light2.position.set(-1, 1, 0);
    this.lights.add(light2);

    const light3 = new DirectionalLight(0xffffff, 0.2);
    light3.position.set(0, -1, 0);
    this.lights.add(light3);

    const url = "px180.png";
    const cubeTexture = new CubeTextureLoader()
      .setPath("../assets/")
      .load([url, url, url, url, url, url]);
    this.scene.environment = cubeTexture;
    this.scene.environmentIntensity = 0.8;
  }

  createObject() {
    this.model = new Group();
    this.scene.add(this.model);

    const cube = new BoxGeometry(1, 1, 1);
    const material = new MeshStandardMaterial({
      color: 0xff00ff,
      metalness: 0,
      roughness: 1,
    });
    const mesh = new Mesh(cube, material);
    // this.model.add(mesh);
  }

  createControls() {
    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
  }

  initEvent() {
    window.addEventListener("resize", this.onWindowResize);
  }

  onWindowResize = () => {
    this.camera.aspect = this.width / this.height;
    this.camera.updateProjectionMatrix();
    this.renderer.setSize(this.width, this.height);
  };

  loadGLTF = (url, factor = 1) => {
    const loader = new GLTFLoader();
    loader.load(url, (gltf) => {
      gltf.scene.scale.set(factor, factor, factor);
      const position = gltf.scene.children[
        parseInt(gltf.scene.children.length / 2)
      ].position
        .clone()
        .multiplyScalar(factor);
      const camPosition = new Vector3(0, 5, 5);
      if (factor < 1) {
        camPosition.multiplyScalar(10);
      }
      camPosition.add(position);
      this.camera.position.copy(camPosition);
      console.log(position, camPosition);
      this.controls.target.copy(position);
      this.model.add(gltf.scene);
      this.controls.update();
    });
  };
}

window.addEventListener("DOMContentLoaded", () => {
  const engine = new Y3DEngine();
  engine.loadGLTF("../assets/水泥抗压抗折万能试验机.glb");
});
